<template lang="html">
  <div class="player__wrapper">
    <div class="player__progress" v-if="showProgress">
      <div class="time">
        <span class="time-now">{{currentTimeFmt}}</span>
        <span class="time-all">-{{leftTimeFmt}}</span>
      </div>
      <div class="player__progress-bar" ref="progressBar">
        <v-slider
          :style="{width: '100%'}"
          v-model="progress"
          :bufferValue="bufferedProgress"
          :bufferTrans="bufferedProgressTrans"
          runwayColor="rgba(255,255,255,0.3)"
          barColor="#fff"
          buttonColor="#fff"
          :isloading="isloading"
          @change="changeProgress">
        </v-slider>
      </div>
    </div>
    <audio-spectrum v-if="!showProgress" :audioIsPlaying="isPlaying"/>

    <div class="player__btn-group" ref="playerBtnGroup">
      <div
        class="prev"
        :class="[!canPrev ? 'disabled' : '']"
        @click="prev">
      </div>
      <div
        ref="playBtn"
        :class="[audioLoaded ? '' : 'disabled', isPlaying ? 'pause' : 'play']"
        @click="playOrPause">
      </div>
      <div
        class="next"
        :class="[!canNext ? 'disabled' : '']"
        @click="next">
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import VSlider from './slider/index'
import AudioSpectrum from './AudioSpectrum.vue'
import { fmtSecToMin } from './common/util'
import {
  getNetworkStatus,
  playAudioByNative,
  pauseAudioByNative,
  resumeAudioByNative,
  stopAudioByNative,
  getAudioProgress,
  seekAudioProgress,
  readContent,
  pauseRead,
  resumeRead,
  cancelRead
} from '../../api'
import { eventTrack } from '../../util/decorator'

var ua = navigator.userAgent;
  // TODO 精确性待改进
var ANDROID = /android/i.test(ua);
var IOS = /iphone|ipad/i.test(ua);
var WP = /windows phone/i.test(ua);

interface PlayerState {
  isPlaying: boolean;
  bufferedProgress: number;
  progress: number;
  totalTime: number;
  currentTime: number;
  progressInterval: any;
  isloading: boolean;
  currentAudio: any;
  bufferedProgressTrans: boolean;
  nextThrottle: boolean;
  prevThrottle: boolean;
}

let loadInterval: any;

export default Vue.extend({
  name: 'Player',

  data () {
    const initialState: PlayerState = {
      isPlaying: false,
      bufferedProgress: 0,
      progress: 0,
      totalTime: 0,
      currentTime: 0,
      progressInterval: {},
      isloading: true,
      currentAudio: null,
      bufferedProgressTrans: false,
      nextThrottle: true,
      prevThrottle: true
    }
    return initialState
  },

  props: {
    canPrev: {
      type: Boolean,
      default: true
    },
    canNext: {
      type: Boolean,
      default: false
    },
    readUrl: {
      type: String
    },
    showProgress: {
      type: Boolean,
      default: false
    },
    audioLoaded: {
      type: Boolean,
      default: false
    }
  },

  computed: {
    currentTimeFmt ():string {
      return fmtSecToMin(this.currentTime)
    },

    leftTime ():number {
      return this.totalTime - this.currentTime
    },

    leftTimeFmt ():string {
      return fmtSecToMin(this.leftTime)
    }
  },

  watch: {
    currentTime (val:number) {
      this.progress = val / this.totalTime * 100
    }
  },

  components: {
    VSlider,
    AudioSpectrum
  },

  mounted () {
    this.hookNetworkChange()
  },

  methods: {
    init () {
      this.initSound()
    },

    /**
    * 加载单独的音频
    * @param index 音频地址在数组中的索引值
    **/
    initSound () {
      setTimeout(() => {
        getNetworkStatus().then(resp => {
          if (resp.data === '0') {
            this.$toast('无法连接网络')
          } else if (resp.data === '2' && !sessionStorage.getItem('fm_celluar_load')) {
            this.$messageBox.confirm('音频文件的播放会消耗您的流量，建议在wifi下打开，是否继续播放').then(() => {
              sessionStorage.setItem('fm_celluar_load', '1')
            })
          } else {
          }
        }).catch(resp => {
          this.$toast(resp.data)
        })
      }, 500)
    },

    /**
     * 切换音频
     * @param selectedAudio 选中的音频
     */
    changeAudio (selectedAudio: any) {
      this.reset()
      this.currentAudio = selectedAudio
      setTimeout(() => {
        // 100毫秒之后播放 否则cancel不能被拦截
        this.changePlay(selectedAudio)
      }, 100)
    },

    /**
     * 切换音频播放
     */
    changePlay (selectedAudio: any) {
      this.bufferedProgress = 100
      getNetworkStatus().then(resp => {
        if (resp.data === 0) {
          this.$toast('无法连接网络')
          this.isloading = false
          this.$emit('load-complete', true)
        } else if (resp.data === 1) {
          this.play(selectedAudio)
        } else if (resp.data === 2 && !sessionStorage.getItem('fm_cellular_load')) {
          this.$messageBox.confirm('音频文件的播放会消耗您的流量，建议在wifi下打开，是否继续播放').then(() => {
            sessionStorage.setItem('fm_cellular_load', '1')
            this.play(selectedAudio)
          }).catch(() => {
            this.isloading = false
            this.$emit('load-complete', true)
          })
        } else if (resp.data === 2 && !!sessionStorage.getItem('fm_cellular_load')) {
          this.play(selectedAudio)
        }
      })
    },

    /**
    * 判断音频播放状态，执行播放还是暂停
    **/
    playOrPause () {
      if (!this.audioLoaded) return
      eventTrack('007003')
      if(this.isPlaying) {
        this.isPlaying = false
        this.pause(this.currentAudio)
      } else {
        getNetworkStatus().then(resp => {
          console.log('network', resp)
          if (resp.data === 0) {
            this.$toast('无法连接网络')
            this.isloading = false
            this.$emit('load-complete', true)
          } else if (resp.data === 1) {
            this.play(this.currentAudio)
          } else if (resp.data === 2 && !sessionStorage.getItem('fm_cellular_load')) {
            this.$messageBox.confirm('音频文件的播放会消耗您的流量，建议在wifi下打开，是否继续播放').then(() => {
              sessionStorage.setItem('fm_cellular_load', '1')
              this.play(this.currentAudio)
            }).catch(() => {
              this.isloading = false
              this.$emit('load-complete', true)
            })
          } else if (resp.data === 2 && !!sessionStorage.getItem('fm_cellular_load')) {
            this.play(this.currentAudio)
          }
        })
      }
    },

    play (selectedAudio: any) {
      if ( this.progress === 0) {
        this.isloading = true
        this.$emit('loadComplete', false)
        if(!selectedAudio.yuyinUrl) {
          readContent(selectedAudio.contentUrl || selectedAudio.url).then((resp: any) => {
            this.isPlaying = true
            this.isloading = false
            this.$emit('load-complete', true)
            this.progress = 100
          })
        } else {
          playAudioByNative(selectedAudio.yuyinUrl, selectedAudio.id, selectedAudio.title).then(resp => {
            this.playCallBack(resp)
          })
        }
      } else {
        if(!this.currentAudio.yuyinUrl) {
          resumeRead().then((resp: any) => {
            this.isPlaying = true
          })
        } else {
          resumeAudioByNative(selectedAudio.yuyinUrl).then(() => {
            this.isPlaying = true
            this.setProgressItv()
          })
        }
      }
    },

    playCallBack (resp: any) {
      !!loadInterval && clearInterval(loadInterval)
        loadInterval = setInterval(() => {
          getAudioProgress().then(resp => {
            if (Number(resp.data.progress) > 0) {
              if(this.totalTime !== resp.data.duration) {
                this.totalTime = resp.data.duration
              }
              this.isPlaying = true
              this.isloading = false
              this.$emit('load-complete', true)
              this.setProgressItv()
              clearInterval(loadInterval)
            }
          })
        }, 500)
    },

    pause (currentAudio: any) {
      if(!currentAudio.yuyinUrl) {
        pauseRead().then((resp: any) => {
          this.isPlaying = false
        })
      } else {
        pauseAudioByNative(currentAudio.yuyinUrl).then(() => {
          this.clearProgressItv()
          this.isPlaying = false
        })
      }
    },

    stop (currentAudio: any) {
      if(!currentAudio.yuyinUrl) {
        cancelRead().then((resp: any) => {
          this.isPlaying = false
        })
      } else {
        stopAudioByNative(currentAudio.yuyinUrl).then(() => {
          this.isPlaying = false
        })
      }
    },

    prev () {
      if (!this.canPrev || !this.prevThrottle) return

      this.prevThrottle = false
      eventTrack('007002')
      this.$emit('prev')
      setTimeout(() => {
        this.prevThrottle = true
      }, 300)
    },

    next () {
      if (!this.canNext || !this.nextThrottle) return

      this.nextThrottle = false
      eventTrack('007004')
      this.$emit('next')
      setTimeout(() => {
        this.nextThrottle = true
      }, 300)
    },

    /**
    * 重置播放器播放状态
    **/
    reset () {
      this.$emit('loadComplete', false)
      this.clearProgressItv()
      this.isPlaying = false
      this.isloading = false
      this.currentTime = 0
      this.progress = 0
      this.bufferedProgress = 0
      if (!!this.currentAudio) {
        this.stop(this.currentAudio)
      }
    },

    /**
    * 改变播放进度条的定时器,间隔1s
    **/
    setProgressItv () {
      this.progressInterval = setInterval(() => {
        if (this.currentTime < this.totalTime) {
          this.currentTime ++
        } else {
          this.reset()
          // 连续播放
          if (!this.isPlaying) this.next()
        }
      }, 1000)
    },

    clearProgressItv () {
      clearInterval(this.progressInterval)
    },

    /**
    * 改变当前音频播放进度
    * @param pecent 进度 [0~100]
    **/
    changeProgress (percent: number) {
      eventTrack('007001')
      let pos = percent / 100
      seekAudioProgress(this.currentAudio.yuyinUrl, pos).then(() => {
        this.progress = percent
        this.currentTime = parseInt(String(this.totalTime * percent / 100))
      })
    },

    /**
    * 恢复音频播放进度条
    * @param index 音频索引
    * @param state 播放状态：0（播放中），1（【不播放】暂停/停止）
    * @param url 音频url
    **/
    resumeProgress (state: number, resumeAudio: any) {
      this.currentAudio = resumeAudio
      getAudioProgress().then(resp => {
        console.warn(resp)
        if (parseInt(resp.data.duration) == 0 && parseInt(resp.data.progress) === 0) {
          state === 0 ? this.isPlaying = true : this.isPlaying = false
        } else {
          let progress =  Number(resp.data.progress)
          this.totalTime = resp.data.duration
          this.isloading = false
          this.currentTime = parseInt(String(this.totalTime * progress))
          if(state === 0) {
            this.isPlaying = true
            this.setProgressItv()
          }
        }
      })
    },

    //向Bridge暴露网络状态变化后的方法
    hookNetworkChange () {
      interface networkChangeRes {
        data: string;
        error?: string;
      }

      if(!Bridge['onNetworkChange']) {
        Bridge.onNetworkChange = (res:string) => {
          let response:networkChangeRes = JSON.parse(res).ret
          if(response.error === '0') {
            if(response.data === '1') {
              this.pause(this.currentAudio)
              this.$messageBox({
                message: '您的wifi已断开，是否继续播放',
                showCancelButton: true,
                confirmButtonText: '继续'})
              .then((action:any) => {
                action === 'confirm' && this.play(this.currentAudio)
              })
            }
          } else {
            console.error('err')
          }
        }
      }

      // setTimeout(() => {
      //   window.onNetworkChange('{"ret":{"error":"0","data":"1"},"jsToken":""}')
      // }, 3000)
    }
  }
})
</script>

<style scoped>
.player__wrapper {
  padding: 0px 5px 0 5px;
  background-color: transparent;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
}
.player__progress {
  width: 100%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.player__progress .time {
  width: 100%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  justify-content: space-between;
}
.player__progress .time-now,
.player__progress .time-all {
  color: #fff;
}
.player__progress-bar {
  width: 100%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  justify-content: center;
}
.player__btn-group {
  position: absolute;
  top: 45px;
  left: 0;
  padding: 0 20%;
  z-index: 2200;
  box-sizing: border-box;
  /*margin-top: 10px;*/
  width: 100%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: 0.3s all;
}
.player__btn-group .play,
.player__btn-group .pause {
  width: 30px;
  height: 30px;
}
.player__btn-group .play.disabled,
.player__btn-group .pause.disabled,
.player__btn-group .prev.disabled,
.player__btn-group .next.disabled {
  opacity: 0.6;
}
.player__btn-group .prev,
.player__btn-group .next {
  width: 25px;
  height: 25px;
}
.player__btn-group .prev {
  background-image: url('../../assets/images/icon_fm_qianyihsou@2x.png');
  background-size: contain;
  background-repeat: no-repeat;
}

.player__btn-group .next {
  transform: rotate(180deg);
  background-image: url('../../assets/images/icon_fm_qianyihsou@2x.png');
  background-size: contain;
  background-repeat: no-repeat;
}

.player__btn-group .play {
  background-image: url('../../assets/images/icon_fm_bofang@2x.png');
  background-size: contain;
  background-repeat: no-repeat;
}

.player__btn-group .pause {
  background-image: url('../../assets/images/icon_fm_zanting@2x.png');
  background-size: contain;
  background-repeat: no-repeat;
}
</style>
